<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //  闭包 closure就是函数套函数  A函数里面包含B函数,B函数可以访问A函数的变量，即使A函数以及执行完毕

        function outer(){
            const a = 1
            function f(){
                console.log(a);
            }
            f()
        }
        outer()

        // 闭包不一定有 return ,闭包也不一定有内存泄漏

        //  什么时候使用return-- 如果外部的想要使用闭包的变量，此时就要return 
        // 闭包实现数据的私有，外面的可以用但是不能修改---react的hooks(有return)大多都是使用这种闭包方式
        
        function outer2(){
            const a2 = 10
            return function f2(){
                console.log(a2);
            }
            f2()
        }
        outer2()

        let i = 0
        function fn(){
            i++
            console.log(`函数被调用了${i}次`);
        }

        function count(){
            let val = 0;
            function fn2(){
                val++
                console.log(`函数被调用了${val}次`);
            }
            // return fn2  // 这里不加() 是等待被调用
            return fn2() // 一旦加了() 就是立即被调用,而且控制台运行fun()会报错，所以一般不这么干
        }
        const fun = count()

        /**
         * 针对上面count()的代码，谁会内存泄露，借助于垃圾回收机制的标记清除法可以看出
         * fun 是一个全局变量，代码执行完毕不会立即销毁
         * fun 使用count 函数
         * count 使用 fn2函数
         * fn2函数里面用到val
         * val 被引用就不会被回收，所以一直存在
         * 此时: 闭包引起了内存泄漏
         * **/ 

        /**
         * 也不是所有的内存泄漏都要手动回收 ，比如react里面的很多闭包就不行
         * **/  
    </script>
</body>
</html>